<?php declare(strict_types=1);


namespace App\Api\V2\Controller\Incoming;

use App\Api\Controllers\BaseController;
use App\Api\Controllers\Config\VbillConfigController;
use App\Models\ExtensionWorkers;
use App\Models\ExtensionWorkerStores;
use App\Models\SmsConfig;
use App\Models\Store;
use App\Models\User;
use App\Models\VbillStore;
use App\Services\PrintSqlService;
use App\Services\Vbill\IncomeResultService;
use App\Traits\ResponseTrait;
use App\Util\ListUtil;
use BaconQrCode\Renderer\ImageRenderer;
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
use BaconQrCode\Writer;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use BaconQrCode\Renderer\Image;

class ExtensionWorkerController extends BaseController
{

    use ResponseTrait;


    public function add(Request $request): string
    {
        $user = $this->parseToken();
        $data = $request->all();
        $validator = Validator::make($data, [
            "phone" => ["required", "regex:/1[0-9]{10}/"],
            "name" => ["required"],
            "status" => ["required"],
            "user_id"=>["required"]
        ]);
        if ($validator->fails()) {
            return $this->errorResponse($validator->errors()->first());
        }
        if (ExtensionWorkers::query()->where("phone", $data["phone"])->first()) {
            return $this->errorResponse("手机号已经添加");
        }

        $url = url('/apply?worker_phone=' . $data["phone"]);//生成的url准备生成二维码;
        try {
            $cno = date("Ymdhis", time()) . rand(1000, 9999);
            //生成二维码文件
            $path = public_path('QrCodeIncoming/' . $cno);
            if (!is_dir($path)) {
                mkdir($path, 0777, true);
            }
            $renderer = new ImageRenderer(new RendererStyle(400), new Image\ImagickImageBackEnd());
            $writer = new Writer($renderer);
            $file_path = $path . '.png';// public_path('QrCodeIncoming/' . $cno . '/' . $code_number . '.png');
            $writer->writeFile($url, $file_path);
        } catch (\Exception $exception) {
            throw new \Exception($exception->getMessage());
        }
        $result = ExtensionWorkers::query()->create([
            "phone" => $data["phone"],
            "name" => $data["name"],
            "status" => $data["status"],
            "user_id" => $data["user_id"]??$user->user_id,
            "link" => $url,
            "path" => url('QrCodeIncoming/' . $cno . '.png'),
            "created_at" => time(),
            "updated_at" => time()
        ]);
        if (empty($result)) {
            return $this->errorResponse("添加失败");
        }
        return $this->successResponse("ok", ["data" => $result->toArray()]);
    }


    public function update(Request $request): string
    {
        $user = $this->parseToken();
        $data = $request->all();
        $validator = Validator::make($data, [
            "id" => ["required"],
            "phone" => ["required", "regex:/1[0-9]{10}/"],
            "name" => ["required"],
        ], []);
        if ($validator->fails()) {
            return $this->errorResponse($validator->errors()->first());
        }
        //手机号是否存在
        $ch = ExtensionWorkers::query()->where("phone", $data["phone"])->where("id", "!=", $data["id"])->first();
        if (!empty($ch)) {
            return $this->errorResponse("手机号已存在");
        }

        $worker = ExtensionWorkers::query()->where("id", $data["id"])->first();
        if (empty($worker)) {
            return $this->errorResponse("推广人员不存在");
        }
        $url = url('/apply?worker_phone=' . $data["phone"]);//生成的url准备生成二维码;
        try {
            $cno = date("Ymdhis", time()) . rand(1000, 9999);
            //生成二维码文件
            $path = public_path('QrCodeIncoming/' . $cno);
            if (!is_dir($path)) {
                mkdir($path, 0777, true);
            }
            $renderer = new ImageRenderer(new RendererStyle(400), new Image\ImagickImageBackEnd());
            $writer = new Writer($renderer);
            $file_path = $path . '.png';// public_path('QrCodeIncoming/' . $cno . '/' . $code_number . '.png');
            $writer->writeFile($url, $file_path);
        } catch (\Exception $exception) {
            throw new \Exception($exception->getMessage());
        }

        $result = $worker->update([
            "phone" => $data["phone"],
            "name" => $data["name"],
            "updated_at" => time(),
            "link" => $url,
            "path" => url('QrCodeIncoming/' . $cno . '.png'),
        ]);

        if (empty($result)) {
            return $this->errorResponse("更新失败");
        }

        return $this->successResponse("更新成功");
    }

    public function status(Request $request): string
    {

        $id = $request->post("id");
        $user = $this->parseToken();
        //状态切换
        $worker = ExtensionWorkers::query()->where("id", $id)->first();
        if (empty($worker)) {
            return $this->errorResponse("工作人员不存在");
        }
        $origin_status = $worker->status;
        $now_status = 0;
        if ($origin_status == 1) {
            $now_status = 0;
        } elseif ($origin_status == 0) {
            $now_status = 1;
        }
        $worker->status = $now_status;
        if (!$worker->save()) {
            return $this->errorResponse("更新失败");
        }

        return $this->successResponse("ok", ["data" => ["status" => $now_status]]);
    }

    public function lists(Request $request): string
    {
        $user = $this->parseToken();
        $page = $request->get("page", 1);
        $pagesize = $request->get("pagesize", 20);
        $user_id = $user->user_id;
        if (!empty($request->get("user_id"))) {
            $user_id = $request->get("user_id");
        }
        $systemUserArray = User::query()->select("id", "pid", "name")->get()->toArray();
        $systemUserArray = ListUtil::createListsNode($systemUserArray);
        $userCollection = ListUtil::getListsNode($systemUserArray, ["id" => $user->user_id]);
        $userCollection = ListUtil::listsNodeToArray([$userCollection]);
        $userCollectionIds = array_column($userCollection, "id");
        if (!in_array($user_id, $userCollectionIds)) {
            return $this->errorResponse("无数据权限");
        }
        $query = ExtensionWorkers::query()->where([
            "user_id" => $user_id,
        ]);
        if ($request->get("status", -1) > -1) {
            $query->where("status", (int)$request->get("status"));
        }

        $list = (clone $query)->offset(($page - 1) * $pagesize)->limit($pagesize)->get()->toArray();

        $total = (clone $query)->count();

        return $this->successResponse("ok", [
            "total" => $total,
            "data" => $list
        ]);

    }

    public function select(Request $request): string
    {
        $user = $this->parseToken();
        $user_id = $user->user_id;
        if (!empty($request->get("user_id"))) {
            $user_id = $request->get("user_id");
        }
        $systemUserArray = User::query()->select("id", "pid", "name")->get()->toArray();
        $systemUserArray = ListUtil::createListsNode($systemUserArray);
        $userCollection = ListUtil::getListsNode($systemUserArray, ["id" => $user_id]);
        $userCollection = ListUtil::listsNodeToArray([$userCollection]);
        $userCollectionIds = array_column($userCollection, "id");

        $query = ExtensionWorkers::query()->whereIn("user_id",$userCollectionIds);
        if ($request->get("status", -1) > -1) {
            $query->where("status", (int)$request->get("status"));
        }

        $list = (clone $query)->get()->toArray();

        return $this->successResponse("ok", ["data"=>$list]);
    }


    public function bind (Request $request)
    {
        $storeId = $request->post('store_id');
        $phone = $request->post('phone');
        $workerId = $request->post('worker_id');
        if ($workerStores = ExtensionWorkerStores::query()->where(["store_id" => $storeId])->first()) {
            return $this->errorResponse("该门店已绑定业务-".$workerStores->phone);
        }
        if (!ExtensionWorkerStores::query()->create(["worker_id" => $workerId, "store_id" => $storeId, "phone" => $phone])) {
            return $this->errorResponse("绑定失败");
        } else {
            return $this->successResponse("绑定成功");
        }
    }

    public function stores (Request $request)
    {
        $user = $this->parseToken();

        $page = $request->get("page", 1);
        $pagesize = $request->get("pagesize", 20);

        $query = ExtensionWorkerStores::query()
            ->leftJoin('stores', 'extension_worker_stores.store_id', 'stores.store_id')
            ->where([
                "extension_worker_stores.worker_id" => $user->wid,
            ])->select('extension_worker_stores.*', 'stores.store_name');

        $list = $query->offset(($page - 1) * $pagesize)->limit($pagesize)->get();
        $total = $query->count();
        return $this->successResponse("ok", [
            "total" => $total,
            "data" => $list
        ]);
    }

    public function goods (Request $request)
    {
        $storeId = $request->input('store_id');
        $code = $request->input('code');
        $page = $request->get("page", 1);
        $pagesize = $request->get("pagesize", 20);
        $query = DB::table('store_goods')->where([
            "store_id" => $storeId
        ]);
        if ($code) {
            $query->where(['code' => $code]);
        }

        $list = $query->offset(($page - 1) * $pagesize)->limit($pagesize)->get();
        $total = $query->count();
        return $this->successResponse("ok", [
            "total" => $total,
            "data" => $list
        ]);
    }

    public function total (Request $request)
    {
        $user = $this->parseToken();
        $storeId = $request->input('store_id');
        $ctime = $request->input('ctime');
        $etime = $request->input('etime');
        $code  = $request->input('code');
        $mod = DB::table('order_goods_details');

        if (!empty($code)) {
            $mod->where('goods_detail', 'like', '%' . $code . '%');
        }
        if (!empty($storeId)) {
            $mod->where(["store_id" => $storeId]);
        } else {
            $storeIds = DB::table('extension_worker_stores')->where(["worker_id" => $user->wid])->get()->toArray();
            $storeIds = array_column($storeIds, "store_id");
            $mod->whereIn("store_id", [$storeIds]);
        }
        if (!empty($ctime) && !empty($etime)) {
            $mod->whereBetween('created_at', [$ctime, $etime]);
        }
        $mod->where(["status" => 1]);
        $count = $mod->count();
        return $this->successResponse("ok", ['count' => $count]);
    }

    public function edit (Request $request)
    {
        $storeId = $request->input('store_id');
        $price = $request->input('price');
        $id  = $request->input('id');
        if (DB::table('store_goods')->where(["store_id" => $storeId])->where(['id' => $id])->update(['price' => $price])) {
            return $this->successResponse("成功");
        } else {
            return $this->errorResponse("失败");
        }
    }

    protected function upOss($file,$fileName="")
    {
        if(empty($file)){
            return "";
        }
        if(!is_dir(public_path()."/threeCode/")){
            mkdir(public_path()."/threeCode/",0755,true);
        }
        if(empty($fileName)){
            $file_path = "/threeCode/".time() . '.' . substr($file, strrpos($file, ".") + 1); // 新文件名
        }else{
            $file_path="/threeCode/".$fileName;
        }
        file_put_contents(public_path() . $file_path,file_get_contents($file));
        $url=url($file_path);
        if(strpos($url,"https")===false){
            $url = str_replace("http", "https", $url);
        }
        return $url;
        //阿里云oss
        $AccessKeyId = env('ALIOSS_AccessKeyId');
        $AccessKeySecret = env('ALIOSS_AccessKeySecret');
        $endpoint = env('ALIOSS_endpoint');
        $bucket = env('ALIOSS_bucket');
        //https://osscdn.suixingpay.com/0/2/32MDJhYjIyYWZoVE5xZTJheDIwMjVfMDdfMTJfMTFfNTVfM2RjNmI5NGY5OTY0NGJlZThmZWUxNWI0ODRkMWYyZTAyYUttY2hfYnVja2V0MmFiMQ.jpg
        $object = "threeCode/".time() . '.' . substr($file, strrpos($file, ".") + 1); // 新文件名
        try {
            $content = file_get_contents($file);
            $ossClient = new \OSS\OssClient($AccessKeyId, $AccessKeySecret, $endpoint);
            $data = $ossClient->putObject($bucket, $object, $content);
            $url = $data['oss-request-url'];
            //删除本地图片
            if(strpos($url,"https")===false){
                $url = str_replace("http", "https", $url);
            }
            return $url;
        } catch (\OSS\Core\OssException $e) {
            Log::info($e->getMessage() . ' | ' . $e->getFile() . ' | ' . $e->getLine());
        }
        return "";
    }
    protected function upSubInfo($subInfo,$store_id,$wx_url,$zfb_url):void
    {
        $up=[
            "store_id"=>$store_id,
        ];
        if(!empty($wx_url)){
            $up["wx_url"]=$wx_url;
        }
        if(!empty($zfb_url)){
            $up["zfb_url"]=$zfb_url;
        }
        if(empty($subInfo)){
            $up["created_at"]=date("Y-m-d H:i:s",time());
            $up["updated_at"]=date("Y-m-d H:i:s",time());
            DB::table("vbill_sub_infos")->insert($up);
        } else{
            $up["updated_at"]=date("Y-m-d H:i:s",time());
            DB::table("vbill_sub_infos")->where("id",$subInfo->id)->update($up);
        }
    }

    protected function weixin_config(\App\Api\Controllers\Vbill\BaseController $obj,$vbill_config,$mno,$subMchId,$subInfo){
        //报备微信授权目录
        $url = $obj->weixin_config;
        $data = [
            'orgId' => $vbill_config->orgId,
            'reqId' => time(),
            'version' => '1.0',
            'timestamp' => date('Ymdhis', time()),
            'signType' => 'RSA',
            'reqData' => [
                'mno' => $mno,
                'subMchId' => $subMchId,
//                                'type'=>'jsapi',
                'type' => '03',
                'jsapiPath' => env('APP_URL') . '/api/vbill/weixin/'
            ],
        ];
//        dump($data);die;
        $result = $obj->execute($data, $url, $vbill_config->privateKey, $vbill_config->sxfpublic);
        $info=$result["data"];

        if(isset($info["respData"]["bizCode"])  && $info["respData"]["bizCode"]=="0000"){
            DB::table("vbill_sub_infos")->where("id",$subInfo->id)->update([
                "is_weixin_config"=>1
            ]);
        }
    }


    public function threeCode (Request $request)
    {
        $storeId = $request->input('store_id');
        $type    = $request->input('type');
        $opt     = $request->input('opt');
        $store   = DB::table('stores')->select('store_name', 'store_short_name')->where(["store_id" => $storeId])->first();
        if(empty($store)){
            return $this->errorResponse("门店不存在");
        }
        if ($type == 1) { //收款码
            $store->qrcode  = env("APP_URL").'/qr?store_id=' . $storeId;
        }
        $subInfo=DB::table("vbill_sub_infos")->where("store_id",$storeId)->first();
        if ($type == 2) { //微信授权码
            $store->weixin_mch_id =empty($subInfo)? "": $subInfo->weixin_mch_id;
            $store->qrcode = empty($subInfo->weixin_mch_id)?"": $subInfo->wx_url;
            if(empty($store->alipay_mch_id)){
                list($isOk,$error) = (new IncomeResultService())->query($storeId);
                if($isOk==false){
                    return $this->errorResponse($error);
                }
            }
            if(!empty($store->qrcode)){
                return $this->successResponse("成功", [
                    "action"=>"query",
                    'store' => $store
                ]);
            }
            $vbill_stores = VbillStore::query()->where(['store_id' => $storeId])->first();
            if(empty($vbill_stores)){
                return $this->errorResponse("随行付商户号不存在");
            }
            $config = new VbillConfigController();
            $vbill_config = $config->vbill_config($vbill_stores->config_id);
            $obj = new \App\Api\Controllers\Vbill\BaseController();
            if(!empty($subInfo) && $subInfo->is_weixin_config==0){
                $this->weixin_config($obj,$vbill_config,$vbill_stores->mno,$subInfo->weixin_mch_id,$subInfo);
            }
            $data = [
                'orgId'     => $vbill_config->orgId,
                'reqId'     => time(),
                'version'   => '1.0',
                'timestamp' => date('Ymdhis', time()),
                'signType'  => 'RSA',
                'reqData'   => [
                    'mno' => $vbill_stores->mno,
                ],
            ];
            if ($opt == 'query') {
                $url = $obj->queryApplyInfo;
                $result = $obj->execute($data, $url, $vbill_config->privateKey, $vbill_config->sxfpublic);
                $info=$result["data"];
                Log::channel("vbill")->info("query", [
                    "url" => $url,
                    "req" => $data,
                    "res" => $result
                ]);
                if($info["code"]!="0000"){
                    return $this->errorResponse("响应异常_".$info["msg"]);
                }
                $url=$this->upOss($info["respData"]["infoQrcode"]??"");
                $store->qrcode = empty($subInfo->weixin_mch_id)?"":$url;
                $this->upSubInfo($subInfo,$storeId,$url,"");
            }
            if ($opt == 'apply') {//申请
                $url = $obj->wechat_commit_apply;
                $result = $obj->execute($data, $url, $vbill_config->privateKey, $vbill_config->sxfpublic);
                $info=$result["data"];
                Log::channel("vbill")->info("apply", [
                    "url" => $url,
                    "req" => $data,
                    "res" => $result
                ]);
                if(isset($info['respData']) && $info['respData']['bizCode'] == '0000' ){
                    return $this->successResponse("ok",[
                        "action"=>"apply",
                        "result"=> "申请成功"
                    ]);
                }else{
                    return $this->errorResponse($info['respData']['bizMsg']??"申请失败");
                }
            }
        }
        if ($type == 3) { //支付宝授权码
            $store->alipay_mch_id =empty($subInfo)?"": $subInfo->alipay_mch_id;
            $store->qrcode = empty($subInfo->alipay_mch_id)?"": $subInfo->zfb_url;
            if(empty($store->alipay_mch_id)){
                list($isOk,$error) = (new IncomeResultService())->query($storeId);
                if($isOk==false){
                    return $this->errorResponse($error);
                }
            }
            if(!empty($store->qrcode)){
                return $this->successResponse("成功", [
                    "action"=>"query",
                    'store' => $store
                ]);
            }
            $vbill_stores = VbillStore::query()->where(['store_id' => $storeId])->first();
            if(empty($vbill_stores)){
                return $this->errorResponse("随行付商户号不存在");
            }
            $config = new VbillConfigController();
            $vbill_config = $config->vbill_config($vbill_stores->config_id);
            $obj = new \App\Api\Controllers\Vbill\BaseController();
            $data = [
                'orgId' => $vbill_config->orgId,
                'reqId' => time(),
                'version' => '1.0',
                'timestamp' => date('Ymdhis', time()),
                'signType' => 'RSA',
                'reqData' => [
                    'mno' => $vbill_stores->mno,
                ],
            ];
            if($opt == 'query'){
                $url = $obj->alipayQueryApplyInfo;
                $result = $obj->execute($data, $url, $vbill_config->privateKey, $vbill_config->sxfpublic);
                $info=$result["data"];
                Log::channel("vbill")->info("query", [
                    "url" => $url,
                    "req" => $data,
                    "res" => $result
                ]);
                if($info["code"]!="0000"){
                    return $this->errorResponse("响应异常_".$info["msg"]);
                }
                $url=$this->upOss($info["respData"]["infoQrcode"]??"",time().".jpg");
                $store->qrcode = empty($subInfo->alipay_mch_id)?"":$url;
                $this->upSubInfo($subInfo,$storeId,"",$url);
            }
            if($opt == 'apply'){
                $url = $obj->alipay_commit_apply;
                $result = $obj->execute($data, $url, $vbill_config->privateKey, $vbill_config->sxfpublic);
                Log::channel("vbill")->info("apply", [
                    "url" => $url,
                    "req" => $data,
                    "res" => $result
                ]);
                $info=$result["data"];
                if(isset($info['respData']) && $info['respData']['bizCode'] == '0000' ){
                    return $this->successResponse("ok",[
                        "action"=>"apply",
                        "result"=> "申请成功"
                    ]);
                }else{
                    return $this->errorResponse($info['respData']['bizMsg']??"申请失败");
                }
            }
        }
        return $this->successResponse("成功", [
            "action"=>"query",
            'store' => $store
        ]);
    }

}